package client

import (
	. "chess_platform/internal/common"
	"errors"
	"fmt"
	"github.com/astaxie/beego/orm"
	"time"
)

//邮件列表, 这没法做缓存，要实时拉取
func ListEmail(cursor, uid int64) ([]*Email, int64, int64, error) {
	o := NewDBOrm(DBChess)
	now := time.Now().Unix()
	expireTime := now - EmailExpire //15天以内的消息才获取
	where := fmt.Sprintf(` ruid = %v AND eid > %v AND send_time >= %v AND send_time <= %v `, uid, cursor, expireTime, now)
	sql := fmt.Sprintf(`
			SELECT
				*
			FROM
				%v
			WHERE
				%v
			ORDER BY
				send_time
			DESC
		`, TableEmailUser, where)
	var email []*Email
	_, err := o.Raw(sql).QueryRows(&email)
	if CheckError(err) {
		return nil, 0, cursor, err
	}
	//由于是按发送时间倒序查找，所以最大的在最前面eid不一定在最前面
	//只能用比较法去查找了
	for _, v := range email {
		if cursor < v.Eid {
			cursor = v.Eid
		}
	}

	sql = fmt.Sprintf(`SELECT COUNT(1) FROM %v WHERE %v`, TableEmailUser, where)
	var count int64
	err = o.Raw(sql).QueryRow(&count)
	return email, count, cursor, err
}

//发送邮件,其实就是插入一条邮件记录
func NewEmail(email map[string]interface{}, multiOrm ...orm.Ormer) (int64, error) {
	o := NewOrm(multiOrm, DBChess)
	values, sql := InsertSql(TableEmailUser, email)
	result, err := o.Raw(sql, values).Exec()
	if err != nil {
		return 0, err
	}
	return result.LastInsertId()
}

//发送邮件,其实就是插入一条邮件记录(同时发送到大厅通知客户端来拉取邮件)
func SendEmailAndNotifyClient(email map[string]interface{}, uid, clubId int64, msg string, multiOrm ...orm.Ormer) error {
	_, err := NewEmail(email, multiOrm...)
	if err != nil {
		return err
	}
	ok := BroadCastMsgToLobby(clubId, GenBroadcastMsg(ModuleEmail, ActionNewEmail, ""), uid)
	if !ok {
		return errors.New("发送邮件通知,游戏服务器大厅返回失败")
	}
	if msg != "" {
		ok = BroadCastMsgToLobby(clubId, msg, uid)
		if !ok {
			return errors.New("发送亲友圈成员变动通知,游戏服务器大厅返回失败")
		}
	}

	return nil
}

//更新邮件
func UpdateEmail(email map[string]interface{}, eid, uid int64) error {
	o := NewDBOrm(DBChess)
	condition := fmt.Sprintf(`eid = %v AND ruid = %v`, eid, uid)
	values, sql := UpdateSql(TableEmailUser, email, condition)
	_, err := o.Raw(sql, values).Exec()
	return err
}

//根据id查找邮件附件
func AttachmentById(eid, uid int64) (*Email, error) {
	sql := fmt.Sprintf(`
		SELECT
			attachment,is_get,operate_type
		FROM
			%v
		WHERE
			eid = ? AND ruid = ?
		LIMIT 1`, TableEmailUser)
	o := NewDBOrm(DBChess)
	var email Email
	err := o.Raw(sql, eid, uid).QueryRow(&email)
	if CheckNoExist(err) {
		return nil, nil
	}
	return &email, err
}

//发送全服邮件
func SendFullMail(uid int64) {
	fullid := GetUserLimit(uid)
	var efulls []EmailFull
	o := NewDBOrm(DBChess)
	//取出所有大于用户的全服邮件的efid的全服邮件
	sql := fmt.Sprintf(`
		SELECT
			*
		FROM
			%v
		WHERE
			efid > %v AND expiretime > %v AND status = 0
	`, TableEmailFull, fullid, time.Now().Unix())
	o.Raw(sql).QueryRows(&efulls)
	if len(efulls) == 0 { //没有最新的全服邮件没取到
		return
	}
	for _, v := range efulls {
		mail := map[string]interface{}{
			"type":         0,
			"suid":         0,
			"nickname":     v.Nickname,
			"ruid":         uid,
			"title":        v.Title,
			"content":      v.Content,
			"attachment":   v.Attachment,
			"status":       0,
			"is_get":       0,
			"send_time":    v.PTime,
			"operate_type": SysOpActivity, //全服邮件领取的钻石都当作是搞活动送出的
		}
		NewEmail(mail, o)
		if v.EFid > fullid {
			fullid = v.EFid
		}
	}
	UpdateUserLimit(uid, fullid)
}
